<?php

namespace app\admins\controller;

use think\facade\Db;

class Products extends Base
{
    /**
     * 类目管理
     */

    // 商品类目
    public function cates()
    {
        $pid = (int)input('get.pid', 0);
        $ppid = (int)input('get.ppid', 0);
        // 返回
        if ($ppid > 0) {
            $parent = Db::table('product_cates')->where('id', $ppid)->find();
            $pid = $parent['pid'];
        }
        $data['pid'] = $pid;
        $data['cates'] = Db::table('product_cates')->where('pid', $pid)->select();
        return view('/products/cates', $data);
    }

    // 添加类目
    public function add_cates()
    {
        $pid = (int)input('get.pid');
        return view('/products/add_cates', ['pid' => $pid]);
    }

    // 保存类目
    public function cate_save()
    {
        $pid = (int)input('post.pid');
        $title = input('post.title');
        !$title && die(json_encode(['code' => 1, 'msg' => '类目名称不能为空']));
        // 检查重复类目
        $check = Db::table('product_cates')->where('pid', $pid)->where('title', $title)->find();
        $check && die(json_encode(['code' => 1, 'msg' => '类目名称已存在']));
        Db::table('product_cates')->insert(['pid' => $pid, 'title' => $title]);
        exit(json_encode(['code' => 0, 'msg' => '添加成功']));
    }

    // 编辑类目
    public function edit_cate()
    {
        $id = (int)input('get.id');
        $cate = Db::table('product_cates')->where('id', $id)->find();
        !$cate && die(json_encode(['code' => 1, 'msg' => '类目不存在']));
        return view('/products/edit_cate', ['cate' => $cate]);
    }

    // 保存编辑类目
    public function edit_cate_save()
    {
        $id = (int)input('post.id');
        $title = input('post.title');
        !$title && die(json_encode(['code' => 1, 'msg' => '请输入类目名称']));
        // 检查重复类目
        $cate = Db::table('product_cates')->where('id', $id)->find();
        !$cate && die(json_encode(['code' => 1, 'msg' => '类目不存在']));
        $cates = Db::table('product_cates')->where('pid', $cate['pid'])->where('title', $title)->find();
        $cates && $cates['id'] !== $id && die(json_encode(['code' => 1, 'msg' => '类目名称已存在']));
        Db::table('product_cates')->where('id', $id)->update(['title' => $title]);
        exit(json_encode(['code' => 0, 'msg' => '保存成功']));
    }

    // 删除类目
    public function delete_cates()
    {
        $id = (int)input('post.id');
        $cate = Db::table('product_cates')->where('id', $id)->find();
        !$cate && die(json_encode(['code' => 1, 'msg' => '该类目不存在']));
        // 检查品牌
        $brand = Db::table('product_brands')->where('cid', $id)->select();
        !$brand->isEmpty() && die(json_encode(['code' => 1, 'msg' => '该类目下存在品牌' . implode(',', $brand->column('title'))]));
        // 检查子分类
        $child = Db::table('product_cates')->where('pid', $id)->select();
        !$child->isEmpty() && die(json_encode(['code' => 1, 'msg' => '该类目下有子类目' . implode(',', $child->column('title'))]));
        Db::table('product_cates')->where('id', $id)->delete();
        exit(json_encode(['code' => 0, 'msg' => '删除成功']));
    }

    /**
     * 品牌管理
     */

    // 品牌列表
    public function brands()
    {
        $map = [];
        $data['search'] = input('get.search');
        if ($data['search']) $map[] = ['title', 'like', '%' . $data['search'] . '%'];
        $data['page'] = max(1, (int)input('get.page'));
        $data['pageSize'] = (int)input('get.limit', 10);
        $brands = Db::table('product_brands')->where($map)->order('id', 'desc')->paginate($data['pageSize']);
        $cates = Db::table('product_cates')->whereIn('id', array_column($brands->items(), 'cid'))->column('*', 'id');
        $data['items'] = array_map(function ($item) use ($cates) {
            $item['cate'] = $cates[$item['cid']]['title'];
            $item['logo'] = $item['logo'] ? '<img src="' . $item['logo'] . '" alt="Logo" style="width:65px;">' : '';
            return $item;
        }, $brands->items());
        $data['total'] = $brands->total();
        return view('/products/brands', $data);
    }

    // 品牌添加
    public function add_brands()
    {
        // 层级下拉框
        // $cates = Db::table('product_cates')->field('id,pid,title')->select();
        // $cates = $this->trees($cates);
        // $cates = array_map(function($item){
        //     $item['title'] = $item['level'] ? str_repeat('&nbsp;&nbsp;&nbsp;', $item['level']) . ' |-' . $item['title'] : $item['title'];
        //     return $item;
        // }, $cates);

        // ajax无限级联动
        if ($this->request->isAjax()) {
            $pid = (int)input('get.pid');
            $cates = Db::table('product_cates')->field('id,pid,title')->where('pid', $pid)->select()->toArray();
            return json(['code' => 0, 'msg' => '', 'data' => $cates]);
        }
        // 联动一级节点
        $data['parent'] = Db::table('product_cates')->field('id,pid,title')->where('pid', 0)->select()->toArray();
        return view('/products/add_brands', $data);
    }

    // 品牌保存
    public function add_save()
    {
        $title = input('post.title');
        !$title && die(json_encode(['code' => 1, 'msg' => '请填写品牌名称']));
        // 联动选择框
        $cids = array_reverse((array)input('post.cid'));
        $cid = (int)current($cids);
        if (!$cid) {
            while (next($cids)) {
                $cid = (int)current($cids);
                if ($cid) break;
            }
        }
        !$cid && die(json_encode(['code' => 1, 'msg' => '请选择所属类目']));
        $logo = input('post.logo');
        $descs = input('post.descs');
        $cate = Db::table('product_cates')->where('id', $cid)->find();
        !$cate && die(json_encode(['code' => 1, 'msg' => '所属类目不存在']));
        $brand = Db::table('product_brands')->where('cid', $cid)->where('title', $title)->find();
        $brand && die(json_encode(['code' => 1, 'msg' => '品牌名称已存在']));
        Db::table('product_brands')->insert(compact('title', 'cid', 'logo', 'descs'));
        exit(json_encode(['code' => 0, 'msg' => '添加成功']));
    }

    // 品牌编辑
    public function edit_brands()
    {
        // ajax无限级联动
        if ($this->request->isAjax()) {
            $pid = (int)input('get.pid');
            $cates = Db::table('product_cates')->field('id,pid,title')->where('pid', $pid)->select()->toArray();
            return json(['code' => 0, 'msg' => '', 'data' => $cates]);
        }

        // 编辑行数据
        $id = (int)input('get.id');
        $row = Db::table('product_brands')->where('id', $id)->find();
        !$row && die(json_encode(['code' => 1, 'msg' => '该品牌不存在']));
        $cates = Db::table('product_cates')->field('id,pid,title')->select()->toArray();
        // 递归父节点
        $parents = $this->parents($cates, $row['cid']);
        // 反转数组
        $parents = array_reverse($parents);
        $parent = array_slice($parents, -1);
        // 当前节点下级节点
        $next = array_filter($cates, function ($item) use ($parent) {
            return $item['pid'] == $parent[0]['id'];
        });
        // 每层兄弟节点
        $parents = array_map(function ($item) use ($cates) {
            $item['siblings'] = array_filter($cates, function ($sibling) use ($item) {
                return $sibling['pid'] === $item['pid'];
            });
            return $item;
        }, $parents);
        return view('/products/edit_brands', compact('row', 'next', 'parents'));
    }

    // 品牌保存编辑
    public function edit_brands_save()
    {
        $id = (int)input('post.id');
        $title = input('post.title');
        !$title && die(json_encode(['code' => 1, 'msg' => '请填写品牌名称']));
        // 联动选择框
        $cids = array_reverse((array)input('post.cid'));
        $cid = (int)current($cids);
        if (!$cid) {
            while (next($cids)) {
                $cid = (int)current($cids);
                if ($cid) break;
            }
        }
        !$cid && die(json_encode(['code' => 1, 'msg' => '请选择所属类目']));
        $logo = input('post.logo');
        $descs = input('post.descs');
        $cate = Db::table('product_cates')->where('id', $cid)->find();
        !$cate && die(json_encode(['code' => 1, 'msg' => '所属类目不存在']));
        $brand = Db::table('product_brands')->where('cid', $cid)->where('title', $title)->find();
        $brand && $brand['id'] !== $id && die(json_encode(['code' => 1, 'msg' => '品牌名称已存在']));
        Db::table('product_brands')->where('id', $id)->update(compact('title', 'cid', 'logo', 'descs'));
        exit(json_encode(['code' => 0, 'msg' => '保存成功']));
    }

    // 品牌删除
    public function delete_brands()
    {
        $id = input('post.id');
        $product = Db::table('product')->whereIn('brand_id', $id)->find();
        $product && die(json_encode(['code' => 1, 'msg' => '该品牌下有商品']));
        Db::table('product_brands')->whereIn('id', $id)->delete();
        exit(json_encode(['code' => 0, 'msg' => '删除成功']));
    }

    /**
     * 商品管理
     */

    // 商品列表
    public function index()
    {
        // $data['pageSize'] = 10;
        // $product = Db::table('product')->order('id', 'desc')->paginate($data['pageSzie']);
        // $brands = Db::table('product_brands')
        //     ->whereIn('id', array_column($product->items(), 'brand_id'))
        //     ->column('*', 'id');
        // $data['items'] = array_map(function($item) use ($brands) {
        //     $item['brand_title'] = isset($brands[$item['brand_id']]) ? $brands[$item['brand_id']]['title'] : '';
        //     return $item;
        // }, $product->items());
        // $data['total'] = $product->total();
        // return view('/products/index', $data);

        if ($this->request->isAjax()) {
            $param = $this->request->param();
            // 搜索
            $map = [];
            if (!empty($param['search'])) {
                foreach ((array)$param['search'] as $k => $v) {
                    if ($v) $map[] = [$k, 'like', "%{$v}%"];
                }
            }
            // 查询
            $list = Db::table('product')->order('id', 'desc')->where($map);
            $data['count'] = $list->count();
            if ($data['count']) {
                $data['code'] = 0;
            } else {
                $data['code'] = 1;
                $data['msg'] = '暂无记录';
            }
            // 分页
            $list = $list->page($param['page'], $param['limit']);
            // 渲染
            $brands = Db::table('product_brands')
                ->whereIn('id', $list->column('brand_id'))
                ->column('*', 'id');
            $data['data'] = $list->select()->map(function ($item) use ($brands) {
                $item['brand_title'] = isset($brands[$item['brand_id']]) ? $brands[$item['brand_id']]['title'] : '';
                $item['img'] = $item['img'] ? '<img src="' . $item['img'] . '" style="width: 50%;height:100%">' : '';
                return $item;
            });
            return json($data);
        }
        $brands = Db::table('product_brands')
            ->field(['id', 'cid', 'title'])
            ->select();
        return view('/products/index', ['brands' => $brands]);
    }

    // 商品添加
    public function add()
    {
        $data['brands'] = Db::table('product_brands')->field('id,title')->select();
        return view('/products/add', $data);
    }

    // 商品保存
    public function save()
    {
        $title = input('post.title');
        $brand_id = (int)input('post.brand_id');
        !$title && $this->errMsg(1, '商品名称不能为空');
        $check = Db::table('product')->where('title', $title)->where('brand_id', $brand_id)->find();
        $check && $this->errMsg(1, '商品名称已存在');
        Db::table('product')->insert($this->request->only(['title', 'brand_id', 'img', 'orig_price', 'min_price']));
        // 附件状态
        $img = input('post.img');
        $img && Db::table('files')->where('path', $img)->update(['status' => 0]);
        $this->errMsg(0, '保存成功');
    }

    // 商品编辑
    public function edit()
    {
        $id = (int)input('get.id');
        $data['row'] = Db::table('product')->where('id', $id)->find();
        !$data['row'] && $this->errMsg(1, '商品不存在');
        $data['brands'] = Db::table('product_brands')->field('id,title')->select();
        return view('/products/edit', $data);
    }

    // 商品保存编辑
    public function save_edit()
    {
        $title = input('post.title');
        $brand_id = (int)input('post.brand_id');
        !$title && $this->errMsg(1, '商品名称不能为空');
        $id = (int)input('post.id');
        $check = Db::table('product')->where('title', $title)->where('brand_id', $brand_id)->find();
        $check && $id !== $check['id'] && $this->errMsg(1, '商品名称重复');
        Db::table('product')->where('id', $id)->update($this->request->only(['title', 'brand_id', 'img', 'orig_price', 'min_price']));
        // 附件状态
        $img = input('post.img');
        $img && Db::table('files')->where('path', $img)->update(['status' => 0]);
        $this->errMsg(0, '修改成功');
    }

    // 商品删除
    public function del()
    {
        $id = input('post.id');
        // 检查是否有规格
        $sku = Db::table('product_sku')->whereIn('pro_id', $id)->find();
        $sku && $this->errMsg(1, '该商品下存在规格');
        Db::table('product')->whereIn('id', $id)->delete();
        $this->errMsg(0, '删除成功');
    }

    /**
     * 商品规格
     */

    // 规格列表
    public function skus()
    {
        $pro_id = (int)input('get.pro_id');
        $lists = Db::table('product_sku')->where('pro_id', $pro_id)->select();
        $product = Db::table('product')->where('id', $pro_id)->find();
        return view('/products/skus', compact('lists', 'product'));
    }

    // 添加规格
    public function add_sku()
    {
        $data['pro_id'] = (int)input('get.pro_id');
        // ajax无限级联动
        if ($this->request->isAjax()) {
            $pid = (int)input('get.pid');
            $cates = Db::table('product_cates')->field('id,pid,title')->where('pid', $pid)->select()->toArray();
            // 获取每一层属性
            $propertys = Db::table('property_names')->where('cid', $pid)->select()->toArray();
            $property_values = Db::table('property_values')->whereIn('name_id', array_column($propertys, 'id'))->select()->toArray();
            $propertys = array_map(function ($item) use ($property_values) {
                $item['values'] = array_values(array_filter($property_values, function ($elem) use ($item) {
                    return $elem['name_id'] === $item['id'];
                }));
                return $item;
            }, $propertys);
            exit(json_encode(['code' => 0, 'msg' => '', 'data' => $cates, 'propertys' => $propertys]));
        }
        // 联动一级节点
        $data['parent'] = Db::table('product_cates')->field('id,pid,title')->where('pid', 0)->select()->toArray();
        return view('/products/add_sku', $data);
    }

    // 规格保存
    public function save_pro_sku()
    {
        $pro_id = (int)input('get.pro_id');
        $datas = $this->request->only(['name_value', 'sku_title', 'price', 'stock', 'status']);
        !$datas && die(json_encode(['code' => 1, 'msg' => '该类目没有设置规格属性']));
        $data = [];
        foreach ($datas['name_value'] as $key => $value) {
            $name_value = $datas['name_value'][$key];
            ksort($name_value);
            $data[$key]['name_value'] = json_encode($name_value);
            foreach (['sku_title', 'price', 'stock', 'status'] as $name) {
                $data[$key][$name] = $datas[$name][$key];
            }
            // 商品ID和规格单号
            $data[$key]['pro_id'] = $pro_id;
            $data[$key]['out_no'] = time() . $pro_id . $key . rand(100, 999);
        }
        Db::table('product_sku')->insertAll($data);
        exit(json_encode(['code' => 0, 'msg' => '保存成功']));
    }

    // 规格编辑
    public function edit_sku()
    {
        $id = (int)input('get.id');
        $data['row'] = Db::table('product_sku')->where('id', $id)->find();
        $data['product'] = Db::table('product')->where('id', $data['row']['pro_id'])->find();
        return view('/products/edit_sku', $data);
    }

    // 规格保存编辑
    public function save_edit_sku()
    {
        $id = (int)input('post.id');
        $check = Db::table('product_sku')->where('id', $id)->find();
        !$check && die(json_encode(['code' => 1, 'msg' => '规格不存在']));

        $data = $this->request->only(['sku_title', 'sku_content', 'price', 'status', 'stock']);
        // 检查重复
        $check = Db::table('product_sku')->where('sku_title', $data['sku_title'])->where('pro_id', $check['pro_id'])->find();
        $check && $check['id'] !== $id && die(json_encode(['code' => 1, 'msg' => '规格名称重复']));

        Db::table('product_sku')->where('id', $id)->update($data);
        // 附件状态
        if (preg_match_all('/<img[^>]*src=["\']([^"\']*\/storage\/.+?\.[^"\']*)["\'][^>]*>/i', $data['sku_content'], $matches)) {
            DB::table('files')->whereIn('file_name', array_unique(array_map('basename', $matches[1])))->update(['status' => 0]);
        }
        exit(json_encode(['code' => 0, 'msg' => '保存成功']));
    }

    // 删除规格
    public function delete_sku()
    {
        $id = input('post.id');
        Db::table('product_sku')->where('id', $id)->delete();
        exit(json_encode(['code' => 0, 'msg' => '删除成功']));
    }

    /**
     * 规格属性名称
     */

    // 规格属性名称列表
    public function property_names()
    {
        $data['pageSize'] = (int)input('get.limit', 10);
        $data['page'] = max(1, (int)input('get.page'));
        $names = Db::table('property_names')->order('id', 'desc')->paginate($data['pageSize']);
        $data['total'] = $names->total();
        $cates = Db::table('product_cates')->field('id,pid,title')->select()->toArray();
        // $cates = Db::table('product_cates')->field('id,pid,title')->whereIn('id', array_column($names->items(), 'cid'))->column('*', 'id');
        $data['items'] = array_map(function ($item) use ($cates) {
            // $item['cate_title'] = isset($cates[$item['cid']]) ? $cates[$item['cid']]['title'] : '';
            $item['cate_title'] = implode(' > ', array_column(array_reverse($this->parents($cates, $item['cid'])), 'title'));
            return $item;
        }, $names->items());
        return view('/products/property_names', $data);
    }

    // 属性名称添加
    public function add_property_name()
    {
        // ajax无限级联动
        if ($this->request->isAjax()) {
            $pid = (int)input('get.pid');
            $cates = Db::table('product_cates')->field('id,pid,title')->where('pid', $pid)->select()->toArray();
            return json(['code' => 0, 'msg' => '', 'data' => $cates]);
        }
        // 联动一级节点
        $data['parent'] = Db::table('product_cates')->field('id,pid,title')->where('pid', 0)->select()->toArray();
        return view('/products/add_property_name', $data);
    }

    // 属性名称保存
    public function  save_property_name()
    {
        $data['title'] = input('post.title');
        !$data['title'] && die(json_encode(['code' => 1, 'msg' => '请填写属性名称']));
        // 联动选择框
        $cids = array_reverse((array)input('post.cid'));
        $cid = (int)current($cids);
        if (!$cid) {
            while (next($cids)) {
                $cid = (int)current($cids);
                if ($cid) break;
            }
        }
        $data['cid'] = $cid;
        !$data['cid'] && die(json_encode(['code' => 1, 'msg' => '请选择所属类目']));
        // 检查重名
        $check = Db::table('property_names')->where('cid', $data['cid'])->where('title', $data['title'])->find();
        $check && die(json_encode(['code' => 1, 'msg' => '属性名称重复']));
        Db::table('property_names')->insert($data);
        exit(json_encode(['code' => 0, 'msg' => '保存成功']));
    }

    // 属性名称编辑
    public function edit_property_name()
    {
        // ajax无限级联动
        if ($this->request->isAjax()) {
            $pid = (int)input('get.pid');
            $cates = Db::table('product_cates')->field('id,pid,title')->where('pid', $pid)->select()->toArray();
            return json(['code' => 0, 'msg' => '', 'data' => $cates]);
        }

        // 编辑行数据
        $id = (int)input('get.id');
        $row = Db::table('property_names')->where('id', $id)->find();
        !$row && die(json_encode(['code' => 1, 'msg' => '该属性名称不存在']));
        $cates = Db::table('product_cates')->field('id,pid,title')->select()->toArray();
        // 递归父节点
        $parents = $this->parents($cates, $row['cid']);
        // 反转数组
        $parents = array_reverse($parents);
        $parent = array_slice($parents, -1);
        // 当前节点下级节点
        $next = array_filter($cates, function ($item) use ($parent) {
            return $item['pid'] == $parent[0]['id'];
        });
        // 每层兄弟节点
        $parents = array_map(function ($item) use ($cates) {
            $item['siblings'] = array_filter($cates, function ($sibling) use ($item) {
                return $sibling['pid'] === $item['pid'];
            });
            return $item;
        }, $parents);
        return view('/products/edit_property_name', compact('row', 'next', 'parents'));
    }

    // 属性名称保存编辑
    public function save_edit_property_name()
    {
        $id = (int)input('post.id');
        $title = input('post.title');
        !$title && die(json_encode(['code' => 1, 'msg' => '请填写属性名称']));
        // 联动选择框
        $cids = array_reverse((array)input('post.cid'));
        $cid = (int)current($cids);
        if (!$cid) {
            while (next($cids)) {
                $cid = (int)current($cids);
                if ($cid) break;
            }
        }
        !$cid && die(json_encode(['code' => 1, 'msg' => '请选择所属类目']));
        $cate = Db::table('product_cates')->where('id', $cid)->find();
        !$cate && die(json_encode(['code' => 1, 'msg' => '所属类目不存在']));
        $property_name = Db::table('property_names')->where('cid', $cid)->where('title', $title)->find();
        $property_name && $property_name['id'] !== $id && die(json_encode(['code' => 1, 'msg' => '属性名称已存在']));
        Db::table('property_names')->where('id', $id)->update(compact('title', 'cid'));
        exit(json_encode(['code' => 0, 'msg' => '保存成功']));
    }

    // 属性名称删除
    public function  del_property_name()
    {
        $id = input('post.id');
        $property_value = Db::table('property_values')->where('name_id', $id)->find();
        $property_value && die(json_encode(['code' => 1, 'msg' => '请先删除属性值']));
        Db::table('property_names')->where('id', $id)->delete();
        exit(json_encode(['code' => 0, 'msg' => '删除成功']));
    }

    /**
     * 商品属性值
     */

    // 商品属性值列表
    public function property_values_list()
    {
        $data['name_id'] = (int)input('get.name_id');
        $data['page'] = max(1, (int)input('get.page'));
        $data['pageSize'] = (int)input('get.limit', 10);
        $values = Db::table('property_values')->where('name_id', $data['name_id'])->order('id', 'desc')->paginate($data['pageSize']);
        $names = Db::table('property_names')->field('id,cid,title')->whereIn('id', array_column($values->items(), 'name_id'))->column('*', 'id');
        $data['items'] = array_map(function ($item) use ($names) {
            $item['name_title'] = isset($names[$item['name_id']]) ? $names[$item['name_id']]['title'] : '';
            return $item;
        }, $values->items());
        $data['total'] = $values->total();
        return view('/products/property_values_list', $data);
    }

    // 添加商品属性值
    public function add_property_value()
    {
        $data['name_id'] = (int)input('get.name_id');
        $data['name_title'] = Db::table('property_names')->where('id', $data['name_id'])->value('title');
        return view('/products/add_property_value', $data);
    }

    // 保存商品属性值
    public function save_property_value()
    {
        $data = $this->request->only(['name_id', 'title']);
        $check = Db::table('property_values')->where($data)->find();
        $check && die(json_encode(['code' => 1, 'msg' => '属性值重复']));
        Db::table('property_values')->insert($data);
        exit(json_encode(['code' => 0, 'msg' => '保存成功']));
    }

    // 编辑商品属性值
    public function edit_property_value()
    {
        $id = (int)input('get.id');
        $data['item'] = Db::table('property_values')->where('id', $id)->find();
        $data['item']['name_title'] = Db::table('property_names')->where('id', $data['item']['name_id'])->value('title');
        return view('/products/edit_property_value', $data);
    }

    // 保存编辑商品属性值
    public function save_edit_property_value()
    {
        $id = (int)input('post.id');
        $title = input('post.title');
        // 检查重复
        $check = Db::table('property_values')->where('id', $id)->find();
        !$check && die(json_encode(['code' => 1, 'msg' => '属性值不存在']));
        $check = Db::table('property_values')->where('name_id', $check['name_id'])->where('title', $title)->column('id');
        $check && !in_array($id, $check) && die(json_encode(['code' => 1, 'msg' => '属性值重名']));
        Db::table('property_values')->where('id', $id)->update(['title' => $title]);
        exit(json_encode(['code' => 0, 'msg' => '修改成功']));
    }

    // 删除商品属性值
    public function del_property_value()
    {
        $id = input('post.id');
        Db::table('property_values')->where('id', $id)->delete();
        exit(json_encode(['code' => 0, 'msg' => '删除成功']));
    }
}
